package org.sgx.gwtsjcltest.client.webcrypt.state;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.sgx.gwtsjcltest.client.webcrypt.Main;

import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.History;

public class StateManager {
	private static StateManager instance;

	Map<String, State> states;

	private StateManager() {
		initStates();
	}

	public static StateManager getInstance() {
		if (instance == null)
			instance = new StateManager();
		return instance;
	}

	public final static String STATE_BASE64 = "base64", 
			STATE_SHA_256 = "sha256", 
			STATE_DEFAULT = STATE_BASE64;

	public final static String HISTORY_PREFIX = "state";

	public static final String[] ALL_STATES = { STATE_BASE64 };


	private void initStates() {
		states = new HashMap<String, State>();

		State state = new State(STATE_BASE64, new Base64());
		states.put(STATE_BASE64, state);
	}

	private void registerForHistoryEvents() {

		History.addValueChangeHandler(new ValueChangeHandler<String>() {
			public void onValueChange(ValueChangeEvent<String> event) {

				String historyToken = event.getValue();
				System.out.println("HISTORY: " + historyToken);

				if (historyToken != null && historyToken.startsWith(HISTORY_PREFIX)) {// .substring(0, HISTORY_PREFIX.length()).equals("page")) {

					State state = searchStateInHistoryToken(historyToken);
					if (state != null) {
						navigate(state.getName());
					}

				} else {
					navigate(STATE_DEFAULT);
				}
			}
		});
	}
	public void navigate(String name) {
		State state = states.get(name);
//		System.out.println("LOADED STATE: "+name+" - "+state.getStateView());
		if (state == null)
			return;
		Main.layout().getBody().showView(state.getStateView());
		
		History.newItem(HISTORY_PREFIX + name);
		notifyAllStateListeners();
	}
	protected State searchStateInHistoryToken(String historyToken) {
		for (int i = 0; i < ALL_STATES.length; i++) {
			String stateName = ALL_STATES[i];
			if (historyToken.contains(stateName)) {
				return states.get(stateName);
			}
		}

		return null;
	}
	// state listeners
		List<StateListener> listeners;

//		@Override
		public void addStateListener(StateListener l) {
			listeners.add(l);
		}
	private void notifyAllStateListeners() {
		for (StateListener l : listeners) {
			l.notifyStateChange(this);
		}
	}


}
